home *** CD-ROM | disk | FTP | other *** search
/ Amiga Tools 5 / Amiga Tools 5.iso / tools / disk-tools / cd-tools / scdplayer / source / scdp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-06-22  |  102.2 KB  |  1,841 lines

  1. #include "SCDP.h"
  2. #include "scdplogo.h"
  3.  
  4. enum ReturnIDs
  5. {
  6.     ID_Play=1, ID_Pause, ID_Stop, ID_Previous, ID_Next, ID_Rewind, ID_FastForward, ID_Eject,
  7.     ID_Volume,ID_ProgramL,ID_Shuffle,ID_Repeat,
  8.     ID_TrackSelect,ID_List,ID_ProgramR,
  9.     ID_Use,ID_Save,ID_Confirm,ID_ChangeActive,ID_PUse,ID_PSave,ID_PInsert,
  10.     /* For menus */
  11.     MEN_PROJECT,MEN_ABOUT,MEN_ABOUTMUI,MEN_QUIT,MEN_SETTINGS,MEN_MUI
  12.  
  13. };
  14.  
  15. #define min(a,b) (((a)<(b))?(a):(b))
  16.  
  17. #define MyImageButton(image,key,help) ImageObject,MUIA_Background,MUII_ButtonBack, ButtonFrame, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image,MUIA_ControlChar, key, MUIA_InputMode,MUIV_InputMode_RelVerify,MUIA_ShortHelp,glstr(help), End
  18. #define MyImage(image) ImageObject, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image, End
  19. #define MyImageButton2(image,key,help) ImageObject, MUIA_Background,MUII_ButtonBack, ButtonFrame, MUIA_Weight, 0, MUIA_Image_Spec,"4:PROGDIR:images/" image,MUIA_ControlChar, key, MUIA_InputMode,MUIV_InputMode_Toggle,MUIA_ShortHelp,glstr(help), End
  20.  
  21. #define max(a,b) ((a)>(b))?(a):(b)
  22. #define min(a,b) ((a)<(b))?(a):(b)
  23.  
  24. /* Function prototypes */
  25. int DoScsiCmd(UBYTE *data, int datasize, UBYTE *cmd, int cmdsize, UBYTE flags);
  26. void CDEject(void);
  27. void CDLoad(void);
  28. void CDStop(void);
  29. void CDGetPos(BOOL settimer);
  30. void CDSetVolume(int volume);
  31. void CDResume(void);
  32. void CDPause(void);
  33. void CDPlay(int start, int length);
  34. void CDReadContents(void);
  35. void DoShuffle(void);
  36. void DoProgram(void);
  37. void FillList(void);
  38.  
  39. /* Some global vars */
  40. enum status_enum {NODISK,STOPPED,PAUSED,PLAYING} status=NODISK;     /* CD status*/
  41. enum pstatus_enum {NORMAL,PROGRAM,SHUFFLE} pstatus=NORMAL;          /* Program status */
  42. UBYTE track=0;                                                      /* Track being played */
  43. ULONG actualindex=0;/* address in actualtrack */
  44. ULONG totalindex=0; /* address in CD */
  45. UBYTE validTOC=0;   /* 1=We have read a valid TOC, 0=No */
  46. UBYTE *TOCbuf;      /* Buffer for Table Of Contents */
  47. UBYTE TOClength;    /* Number of tracks */
  48. UBYTE TOCflags[100];/* 0=CDDA, 1=Data */
  49. ULONG TOCaddr[100]; /* Track starts */
  50. char TOCCDID[20];           /* Id string of CD */
  51. char TOCCDtitle[128];       /* Title of actual CD */
  52. char TOCCDartist[128];      /* Artist */
  53.  
  54. UBYTE programmed[101];  /* List of programmed/shuffled tracks */
  55. UBYTE pprog[101];      /* Definitely programmed tracks */
  56. UBYTE pactual;
  57.  
  58. BOOL refresh=FALSE;
  59. BOOL trayout=FALSE;     /* For Eject/Load */
  60. BOOL onevalid=FALSE;     /* Is there at least one CDDA track? */
  61.  
  62. BOOL userstop=TRUE; /* We want CDROM stopped */
  63. UBYTE actuate=0;
  64. UBYTE skip=3;       /* Kludge for waiting for a track's begin */
  65.  
  66. /* Global vars for timing */
  67. struct timerequest *tioreq;
  68. MSGPORT *tmsgport;
  69.  
  70. /* Global vars for SCSI control */
  71. IOSTDREQ *ioreq;
  72. MSGPORT *msgport;
  73. UBYTE *scsidata;
  74. SCSICMD *scsicmd;
  75. UBYTE *scsisense;
  76.  
  77. UBYTE scsidev[256]="scsi.device";
  78. int scsiid=4;
  79. BOOL volumecontrol=TRUE;
  80.  
  81. /* For the logo */
  82. static struct BitMap logobm=
  83. {
  84.     30,
  85.     30,
  86.     0,
  87.     2,
  88.     PAD,
  89.     (UBYTE *)logoplane0,
  90.     (UBYTE *)logoplane1,
  91.     NULL,NULL,NULL,NULL,NULL,NULL
  92. };
  93.  
  94. const ULONG logocolours[]=
  95. {
  96.     0xc0c0c0c0, 0xc0c0c0c0, 0xc0c0c0c0,
  97.     0x00000000, 0x00000000, 0x00000000,
  98.     0xffffffff, 0xffffffff, 0xffffffff,
  99.     0x46464646, 0x7c7c7c7c, 0xbbbbbbbb
  100. };
  101.  
  102. /* For the menu */
  103. static struct NewMenu menudata[]=
  104. {
  105.     { NM_TITLE, NULL,           0, 0, 0,    (APTR)MEN_PROJECT   },
  106.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_ABOUT     },
  107.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_ABOUTMUI  },
  108.     { NM_ITEM,  NM_BARLABEL,    0, 0, 0,    (APTR)0             },
  109.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_QUIT      },
  110.     { NM_TITLE, NULL,           0, 0, 0,    (APTR)MEN_SETTINGS  },
  111.     { NM_ITEM,  NULL,           0, 0, 0,    (APTR)MEN_MUI       },
  112.     { NM_END,NULL,0,0,0,(APTR)0 },
  113. };
  114.  
  115. static APTR AP_SCDP=NULL;
  116. static APTR WI_SCDP,WI_List,WI_Program;
  117. static APTR TX_Track,TX_TitleTime,TX_CDTime,TX_Artist,TX_Title;
  118. static APTR BT_Play,BT_Pause,BT_Stop,BT_Previous,BT_Next,BT_Rewind,BT_FastForward,BT_Eject,BT_Shuffle,BT_ProgramL,BT_Repeat;
  119. static APTR BT_ProgramR,BT_List;
  120. static APTR SL_Volume;
  121. static APTR ST_Artist,ST_CDTitle,ST_Title,LV_TrackSelect,LV_TitleList,BT_Use,BT_Save,BT_Cancel;
  122. static APTR LV_PList,LI_PList,LV_Program,BT_PUse,BT_PSave,BT_PCancel,BT_PNew,BT_PDelete,BT_PUp,BT_PDown,BT_PTop,BT_PBottom;
  123. static APTR MN_Menu, WI_AboutMUI=NULL;
  124.  
  125. /* New for V1.3 */
  126.  
  127. static APTR CH_AutoPlay,CH_AutoProgram,CH_AutoShuffle,CH_AutoRepeat;
  128.  
  129. struct TextFont *getfont(char *name)
  130. {
  131.     char buff[100];
  132.     int i;
  133.     struct TextAttr ta;
  134.  
  135.     i=0;
  136.     while((buff[i]=name[i])!='/' && buff[i]!='\0')
  137.         i++;
  138.  
  139.     if(!buff[i])
  140.         return NULL;
  141.  
  142.     buff[i]='\0';
  143.     strcat(buff,".font");
  144.  
  145.     ta.ta_Name=buff;
  146.     ta.ta_YSize=atoi(name+i+1);
  147.     ta.ta_Style=0;
  148.     ta.ta_Flags=0;
  149.  
  150.     return OpenDiskFont(&ta);
  151. }
  152.  
  153. /* I will try here to program some drag&drop for program window */
  154. /* See DragnDrop.c in MUI examples */
  155. struct ProgramList_Data
  156. {
  157.     LONG dummy;
  158. };
  159.  
  160. ULONG ProgramList_DragQuery(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  161. {
  162.     if(msg->obj==obj)
  163.         return(DoSuperMethodA(cl,obj,msg));
  164.     else if(msg->obj==(Object *)LI_PList) /* Hard coded source list */
  165.         return(MUIV_DragQuery_Accept);
  166.     else
  167.         return(MUIV_DragQuery_Refuse);
  168. }
  169.  
  170. ULONG ProgramList_DragDrop(struct IClass *cl, Object *obj, struct MUIP_DragDrop *msg)
  171. {
  172.     if(msg->obj==obj)
  173.         return(DoSuperMethodA(cl,obj,msg));
  174.     else
  175.     {
  176.         char *entry;
  177.         LONG dropmark;
  178.  
  179.         DoMethod(msg->obj,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&entry);
  180.  
  181.         get(obj,MUIA_List_DropMark,&dropmark);
  182.         DoMethod(obj,MUIM_List_InsertSingle,entry,dropmark);
  183.  
  184.         get(obj,MUIA_List_InsertPosition,&dropmark);
  185.         set(obj,MUIA_List_Active,dropmark);
  186.         set(msg->obj,MUIA_List_Active,MUIV_List_Active_Off);
  187.  
  188.         return 0;
  189.     }
  190. }
  191.  
  192. SAVEDS ASM ULONG ProgramList_Dispatcher(REG(a0) struct IClass *cl,REG(a2) Object *obj,REG(a1) Msg msg)
  193. {
  194.     switch(msg->MethodID)
  195.     {
  196.         case MUIM_DragQuery:    return ProgramList_DragQuery(cl,obj,(APTR)msg);
  197.         case MUIM_DragDrop:     return ProgramList_DragDrop(cl,obj,(APTR)msg);
  198.     }
  199.     return DoSuperMethodA(cl,obj,msg);
  200. }
  201.  
  202. /* Main program at last */
  203. int main(int argc, char *argv[])
  204. {
  205.     char *errorstr=NULL;
  206.     int i,vamos,a,b;
  207.     ULONG signals;
  208.     char buff[256];
  209.     UBYTE *strptr=NULL;
  210.     struct DiskObject *mydo;
  211.     FILE *f;
  212.  
  213.     if(stacksize()<STACKSIZE)
  214.         fail(NULL,glstr(MSG_FailStack));
  215.  
  216.     if(argc==0)
  217.     {
  218.         argc=_WBArgc;
  219.         argv=_WBArgv;
  220.     }
  221.  
  222.     i=strlen(argv[0]);
  223.     while(argv[0][i]!='/' && argv[0][i]!=':' && i)
  224.         i--;
  225.  
  226.     if(argv[0][i]=='/' || argv[0][i]==':')
  227.         sprintf(buff,"PROGDIR:%s",argv[0]+i+1);
  228.     else
  229.         sprintf(buff,"PROGDIR:%s",argv[0]);
  230.  
  231.     init();
  232.  
  233.     mydo=GetDiskObject(buff);
  234.  
  235.     for(a=1;a<argc;a++)
  236.     {
  237.         if(!strncmp(argv[a],"DEVICE=",7))
  238.             strcpy(scsidev,argv[a]+7);
  239.         if(!strncmp(argv[a],"UNIT=",5))
  240.             scsiid=atoi(argv[a]+5);
  241.         if(!strcmp(argv[a],"NOVOLUME"))
  242.             volumecontrol=FALSE;
  243.         if(!strcmp(argv[a],"CUSTOMFONTS"))
  244.             customfonts=TRUE;
  245.         if(!strncmp(argv[a],"NORMALFONT=",11))
  246.             normalname=argv[a]+11;
  247.         if(!strncmp(argv[a],"TINYFONT=",9))
  248.             tinyname=argv[a]+9;
  249.         if(!strncmp(argv[a],"FIXEDFONT=",10))
  250.             fixedname=argv[a]+10;
  251.         if(!strncmp(argv[a],"LISTFONT=",9))
  252.             listname=argv[a]+9;
  253.         if(!strncmp(argv[a],"TITLEFONT=",10))
  254.             titlename=argv[a]+10;
  255.     }
  256.  
  257.     if(customfonts)
  258.     {
  259.         normalfont=getfont(normalname);
  260.         tinyfont=getfont(tinyname);
  261.         fixedfont=getfont(fixedname);
  262.         listfont=getfont(listname);
  263.         titlefont=getfont(titlename);
  264.  
  265.         if(!normalfont || !tinyfont || !fixedfont || !listfont || !titlefont)
  266.             fail(NULL,glstr(MSG_FailNoFont));
  267.     }
  268.  
  269.     if(msgport=CreateMsgPort())
  270.     {
  271.         if(ioreq=CreateIORequest(msgport,sizeof(IOSTDREQ)))
  272.         {
  273.             if(!(OpenDevice(scsidev,scsiid,(struct IORequest *)ioreq,0)))
  274.             {
  275.                 if(scsicmd=AllocMem(sizeof(SCSICMD), MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  276.                 {
  277.                     if(scsisense=AllocMem(SENSE_LEN, MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  278.                     {
  279.                         if(tmsgport=CreateMsgPort())
  280.                         {
  281.                             if(tioreq=CreateIORequest(tmsgport,sizeof(struct timerequest)))
  282.                             {
  283.                                 if(!(OpenDevice(TIMERNAME,UNIT_VBLANK,(struct IORequest *)tioreq,0)))
  284.                                 {
  285.                                     if(scsidata=AllocMem(MAX_DATA_LEN,MEMF_CHIP|MEMF_CLEAR|MEMF_PUBLIC))
  286.                                     {
  287.                                         if(TOCbuf=AllocMem(MAX_TOC_LEN,MEMF_CHIP|MEMF_PUBLIC))
  288.                                         {
  289.                                             programmed[0]=0;
  290.  
  291.                                             menudata[0].nm_Label=glstr(MSG_MenuProject);
  292.                                             menudata[1].nm_Label=glstr(MSG_MenuAbout);
  293.                                             menudata[1].nm_CommKey=glstr(MSG_MenuAboutKey);
  294.                                             menudata[2].nm_Label=glstr(MSG_MenuAboutMUI);
  295.                                             menudata[4].nm_Label=glstr(MSG_MenuQuit);
  296.                                             menudata[4].nm_CommKey=glstr(MSG_MenuQuitKey);
  297.                                             menudata[5].nm_Label=glstr(MSG_MenuSettings);
  298.                                             menudata[6].nm_Label=glstr(MSG_MenuMUI);
  299.  
  300.                                             CL_ProgramList=MUI_CreateCustomClass(NULL,MUIC_List,NULL,sizeof(struct ProgramList_Data),ProgramList_Dispatcher);
  301.  
  302.                                             if(CL_ProgramList)
  303.                                             {
  304.                                                 AP_SCDP = ApplicationObject,
  305.                                                     MUIA_Application_Title,         "SCDPlayer",
  306.                                                     MUIA_Application_Version,       "$VER: SCDPlayer " VERSION " (" __DATE__ " " __TIME__ ")",
  307.                                                     MUIA_Application_Copyright,     "Copyright ©1996, Juan J. García de Soria",
  308.                                                     MUIA_Application_Author,        "Juan J. García de Soria",
  309.                                                     MUIA_Application_Description,   glstr(MSG_SCDPDescription),
  310.                                                     MUIA_Application_Base,          "SCDP",
  311.                                                     MUIA_Application_DiskObject,    mydo,
  312.                                                     MUIA_Application_Menustrip,MN_Menu=MUI_MakeObject(MUIO_MenustripNM,menudata,0),
  313.                                                     SubWindow,
  314.                                                         WI_SCDP=WindowObject,
  315.                                                         MUIA_Window_Title, "SCDPlayer " VERSION,
  316.                                                         MUIA_Window_ID,MAKE_ID('S','C','D','P'),
  317.                                                         WindowContents,HGroup,
  318.                                                             MUIA_Background,MUII_WindowBack,
  319.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  320.                                                             Child,VGroup,   /* Lado izquierdo de la ventana */
  321.                                                                 MUIA_Background,MUII_WindowBack,
  322.                                                                 MUIA_Weight,1,
  323.                                                                 Child,VGroup,
  324.                                                                     MUIA_VertDisappear,1,
  325.                                                                     MUIA_Background,MUII_TextBack,
  326.                                                                     MUIA_Weight,70,
  327.                                                                     TextFrame,
  328.                                                                     Child,VSpace(0),
  329.                                                                     Child,HGroup,
  330.                                                                         Child,HSpace(0),
  331.                                                                         Child,BitmapObject,
  332.                                                                             MUIA_FixWidth,232,
  333.                                                                             MUIA_FixHeight,30,
  334.                                                                             MUIA_Bitmap_Bitmap,&logobm,
  335.                                                                             MUIA_Bitmap_Transparent,0,
  336.                                                                             MUIA_Bitmap_Width,232,
  337.                                                                             MUIA_Bitmap_Height,30,
  338.                                                                             MUIA_Bitmap_SourceColors,logocolours,
  339.                                                                             End,
  340.                                                                         Child,HSpace(0),
  341.                                                                         End,
  342.                                                                     Child,VSpace(0),
  343.                                                                     End,
  344.                                                                 Child,VGroup,   /* Zona de estado */
  345.                                                                     MUIA_VertDisappear,2,
  346.                                                                     MUIA_Background,MUII_TextBack,
  347.                                                                     GroupFrame,
  348.                                                                     MUIA_ShortHelp,glstr(MSG_HelpInfo),
  349.                                                                     Child,VSpace(0),
  350.                                                                     Child,HGroup,   /* Los tres indicadores */
  351.                                                                         Child,VGroup,   /* Nº de pista */
  352.                                                                             MUIA_Weight,0,
  353.                                                                             Child,TextObject,
  354.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  355.                                                                                 MUIA_Text_Contents,glstr(MSG_Track),
  356.                                                                                 MUIA_Text_PreParse,"\33l",
  357.                                                                                 End,
  358.                                                                             Child,TX_Track=TextObject,
  359.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  360.                                                                                 MUIA_Text_Contents,"--",
  361.                                                                                 MUIA_Text_PreParse,"\33l",
  362.                                                                                 End,
  363.                                                                             End,
  364.                                                                         Child,HSpace(0),
  365.                                                                         Child,VGroup,   /* Posición en pista actual */
  366.                                                                             MUIA_Weight,0,
  367.                                                                             Child,TextObject,
  368.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  369.                                                                                 MUIA_Text_Contents,glstr(MSG_TitleTime),
  370.                                                                                 MUIA_Text_PreParse,"\33l",
  371.                                                                                 End,
  372.                                                                             Child,TX_TitleTime=TextObject,
  373.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  374.                                                                                 MUIA_Text_Contents,"--:--/--:--",
  375.                                                                                 MUIA_Text_PreParse,"\33l",
  376.                                                                                 End,
  377.                                                                             End,
  378.                                                                         Child,HSpace(0),
  379.                                                                         Child,VGroup,   /* Posición en todo el CD */
  380.                                                                             MUIA_Weight,0,
  381.                                                                             Child,TextObject,
  382.                                                                                 MUIA_Font,(customfonts)?(ULONG)tinyfont:MUIV_Font_Tiny,
  383.                                                                                 MUIA_Text_Contents,glstr(MSG_CDTime),
  384.                                                                                 MUIA_Text_PreParse,"\33l",
  385.                                                                                 End,
  386.                                                                             Child,TX_CDTime=TextObject,
  387.                                                                                 MUIA_Font,(customfonts)?(ULONG)fixedfont:MUIV_Font_Fixed,
  388.                                                                                 MUIA_Text_Contents,"--:--/--:--",
  389.                                                                                 MUIA_Text_PreParse,"\33l",
  390.                                                                                 End,
  391.                                                                             End,
  392.                                                                         End,
  393.                                                                     Child,TX_Artist=TextObject,
  394.                                                                         MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  395.                                                                         MUIA_Text_SetMin,FALSE,
  396.                                                                         MUIA_Text_Contents,glstr(MSG_NoDisc),
  397.                                                                         MUIA_Text_PreParse,"\33l",
  398.                                                                         End,
  399.                                                                     Child,TX_Title=TextObject,
  400.                                                                         MUIA_Text_SetMin,FALSE,
  401.                                                                         MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  402.                                                                         MUIA_Text_Contents,"",
  403.                                                                         MUIA_Text_PreParse,"\33l",
  404.                                                                         End,
  405.                                                                     Child,VSpace(0),
  406.                                                                     End,
  407.                                                                 Child,HGroup,
  408.                                                                     MUIA_Background,MUII_GroupBack,
  409.                                                                     GroupFrame,
  410.                                                                     Child,HSpace(0),
  411.                                                                     Child,VGroup,
  412.                                                                         Child,VSpace(0),
  413.                                                                         Child,HGroup,
  414.                                                                             MUIA_Weight,0,
  415.                                                                             Child,BT_Play=MyImageButton("Play",' ',MSG_HelpPlay),
  416.                                                                             Child,BT_Pause=MyImageButton("Pause",'.',MSG_HelpPause),
  417.                                                                             Child,BT_Stop=MyImageButton("Stop",'s',MSG_HelpStop),
  418.                                                                             Child,BT_Previous=MyImageButton("Previous",'p',MSG_HelpPrevious),
  419.                                                                             Child,BT_Next=MyImageButton("Next",'n',MSG_HelpNext),
  420.                                                                             Child,BT_Rewind=MyImageButton("Rewind",'r',MSG_HelpRewind),
  421.                                                                             Child,BT_FastForward=MyImageButton("FastForward",'f',MSG_HelpFastForward),
  422.                                                                             Child,BT_Eject=MyImageButton("Eject",'e',MSG_HelpEject),
  423.                                                                             End,
  424.                                                                         Child,HGroup,
  425.                                                                             Child,MyImage("VolumeLow"),
  426.                                                                             Child,SL_Volume=SliderObject,
  427.                                                                                 MUIA_ShortHelp,glstr(MSG_HelpVolume),
  428.                                                                                 MUIA_Slider_Min,1,
  429.                                                                                 MUIA_Slider_Max,31,
  430.                                                                                 MUIA_Slider_Level,16,
  431.                                                                                 MUIA_Slider_Quiet,TRUE,
  432.                                                                                 End,
  433.                                                                             Child,MyImage("VolumeHigh"),
  434.                                                                             Child,BT_ProgramL=MyImageButton2("Program",'o',MSG_HelpProgramL),
  435.                                                                             Child,BT_Shuffle=MyImageButton2("Shuffle",'q',MSG_HelpShuffle),
  436.                                                                             Child,BT_Repeat=MyImageButton2("Repeat",'a',MSG_HelpRepeat),
  437.                                                                             End,
  438.                                                                         Child,VSpace(0),
  439.                                                                         End,
  440.                                                                     Child,HSpace(0),
  441.                                                                     End,
  442.                                                                 End,
  443.                                                             Child,VGroup,   /* Lado derecho de la ventana */
  444.                                                                 MUIA_HorizDisappear,1,
  445.                                                                 MUIA_Background,MUII_GroupBack,
  446.                                                                 GroupFrame,
  447.                                                                 MUIA_Weight,99,
  448.                                                                 Child,LV_TrackSelect=ListviewObject,
  449.                                                                     MUIA_ShortHelp,glstr(MSG_HelpTrackSelect),
  450.                                                                     MUIA_Listview_List,ListObject,
  451.                                                                         ReadListFrame,
  452.                                                                         MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  453.                                                                         MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  454.                                                                         MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  455.                                                                         MUIA_Background,MUII_ListBack,
  456.                                                                         End,
  457.                                                                     End,
  458.                                                                 Child,HGroup,
  459.                                                                     MUIA_VertDisappear,1,
  460.                                                                     Child,BT_List=SimpleButton(glstr(MSG_ListButton)),
  461.                                                                     Child,BT_ProgramR=SimpleButton(glstr(MSG_ProgramButton)),
  462.                                                                     End,
  463.                                                                 End,
  464.                                                             End,
  465.                                                         End,
  466.                                                     SubWindow,
  467.                                                         WI_List=WindowObject,
  468.                                                         MUIA_Window_Title, glstr(MSG_CDInformation),
  469.                                                         MUIA_Window_ID,MAKE_ID('L','I','S','T'),
  470.                                                         WindowContents,VGroup,
  471.                                                             MUIA_Background,MUII_WindowBack,
  472.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  473.                                                             Child,ColGroup(2),
  474.                                                                 Child,Label2(glstr(MSG_Artist)),
  475.                                                                 Child,ST_Artist=StringObject,
  476.                                                                     StringFrame,
  477.                                                                     MUIA_ShortHelp,glstr(MSG_HelpArtist),
  478.                                                                     MUIA_String_MaxLen,127,
  479.                                                                     End,
  480.                                                                 Child,Label2(glstr(MSG_CDTitle)),
  481.                                                                 Child,ST_CDTitle=StringObject,
  482.                                                                     StringFrame,
  483.                                                                     MUIA_ShortHelp,glstr(MSG_HelpCDTitle),
  484.                                                                     MUIA_String_MaxLen,127,
  485.                                                                     End,
  486.                                                                 End,
  487.                                                             Child,TextObject,
  488.                                                                 MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  489.                                                                 MUIA_Text_Contents,glstr(MSG_TitleList),
  490.                                                                 MUIA_Text_PreParse,"\33c",
  491.                                                                 End,
  492.                                                             Child,LV_TitleList=ListviewObject,
  493.                                                                 MUIA_Listview_List,ListObject,
  494.                                                                     MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  495.                                                                     MUIA_ShortHelp,glstr(MSG_HelpTitles),
  496.                                                                     InputListFrame,
  497.                                                                     MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  498.                                                                     MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  499.                                                                     MUIA_Background,MUII_ListBack,
  500.                                                                     End,
  501.                                                                 End,
  502.                                                             Child,ST_Title=StringObject,
  503.                                                                 StringFrame,
  504.                                                                 MUIA_ShortHelp,glstr(MSG_HelpTitle),
  505.                                                                 MUIA_String_MaxLen,127,
  506.                                                                 MUIA_String_AttachedList,LV_TitleList,
  507.                                                                 End,
  508.                                                             Child,ColGroup(4),
  509.                                                                 Child,Label1(glstr(MSG_AutoPlay)),
  510.                                                                 Child,CH_AutoPlay=CheckMarkH(0,glstr(MSG_HelpAutoPlay)),
  511.                                                                 Child,Label1(glstr(MSG_AutoProgram)),
  512.                                                                 Child,CH_AutoProgram=CheckMarkH(0,glstr(MSG_HelpAutoProgram)),
  513.                                                                 Child,Label1(glstr(MSG_AutoShuffle)),
  514.                                                                 Child,CH_AutoShuffle=CheckMarkH(0,glstr(MSG_HelpAutoShuffle)),
  515.                                                                 Child,Label1(glstr(MSG_AutoRepeat)),
  516.                                                                 Child,CH_AutoRepeat=CheckMarkH(0,glstr(MSG_HelpAutoRepeat)),
  517.                                                                 End,
  518.                                                             Child,HGroup,
  519.                                                                 Child,BT_Use=SimpleButton(glstr(MSG_Use)),
  520.                                                                 Child,BT_Save=SimpleButton(glstr(MSG_Save)),
  521.                                                                 Child,BT_Cancel=SimpleButton(glstr(MSG_Cancel)),
  522.                                                                 End,
  523.                                                             End,
  524.                                                         End,
  525.                                                     SubWindow,
  526.                                                         WI_Program=WindowObject,
  527.                                                         MUIA_Window_Title,glstr(MSG_ProgramWindowTitle),
  528.                                                         MUIA_Window_ID,MAKE_ID('P','R','O','G'),
  529.                                                         WindowContents,VGroup,
  530.                                                             MUIA_Font,(customfonts)?(ULONG)normalfont:MUIV_Font_Normal,
  531.                                                             MUIA_Background,MUII_WindowBack,
  532.                                                             Child,HGroup,
  533.                                                                 Child,VGroup,
  534.                                                                     Child,TextObject,
  535.                                                                         MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  536.                                                                         MUIA_Text_Contents,glstr(MSG_TitleList),
  537.                                                                         MUIA_Text_PreParse,"\33c",
  538.                                                                         End,
  539.                                                                     Child,LV_PList=ListviewObject,
  540.                                                                         MUIA_Listview_DragType,MUIV_Listview_DragType_Immediate,
  541.                                                                         MUIA_Listview_List,LI_PList=ListObject,
  542.                                                                             MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  543.                                                                             InputListFrame,
  544.                                                                             MUIA_ShortHelp,glstr(MSG_HelpPTitles),
  545.                                                                             MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  546.                                                                             MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  547.                                                                             MUIA_Background,MUII_ListBack,
  548.                                                                             End,
  549.                                                                         End,
  550.                                                                     End,
  551.                                                                 Child,VGroup,
  552.                                                                     MUIA_Weight,0,
  553.                                                                     Child,VSpace(0),
  554.                                                                     Child,BT_PNew=SimpleButton(glstr(MSG_New)),
  555.                                                                     Child,BT_PDelete=SimpleButton(glstr(MSG_Delete)),
  556.                                                                     Child,BT_PTop=SimpleButton(glstr(MSG_Top)),
  557.                                                                     Child,BT_PUp=SimpleButton(glstr(MSG_Up)),
  558.                                                                     Child,BT_PDown=SimpleButton(glstr(MSG_Down)),
  559.                                                                     Child,BT_PBottom=SimpleButton(glstr(MSG_Bottom)),
  560.                                                                     Child,VSpace(0),
  561.                                                                     End,
  562.                                                                 Child,VGroup,
  563.                                                                     Child,TextObject,
  564.                                                                         MUIA_Font,(customfonts)?(ULONG)titlefont:MUIV_Font_Title,
  565.                                                                         MUIA_Text_Contents,glstr(MSG_ProgramList),
  566.                                                                         MUIA_Text_PreParse,"\33c",
  567.                                                                         End,
  568.                                                                     Child,LV_Program=ListviewObject,
  569.                                                                         MUIA_Listview_DragType,MUIV_Listview_DragType_Immediate,
  570.                                                                         MUIA_Listview_List,NewObject(CL_ProgramList->mcc_Class,NULL,
  571.                                                                             MUIA_Font,(customfonts)?(ULONG)listfont:MUIV_Font_List,
  572.                                                                             InputListFrame,
  573.                                                                             MUIA_List_DragSortable,TRUE,
  574.                                                                             MUIA_ShortHelp,glstr(MSG_HelpProgramList),
  575.                                                                             MUIA_List_ConstructHook,MUIV_List_ConstructHook_String,
  576.                                                                             MUIA_List_DestructHook,MUIV_List_DestructHook_String,
  577.                                                                             MUIA_Background,MUII_ListBack,
  578.                                                                             TAG_DONE),
  579.                                                                         End,
  580.                                                                     End,
  581.                                                                 End,
  582.                                                             Child,HGroup,
  583.                                                                 Child,BT_PUse=SimpleButton(glstr(MSG_Use)),
  584.                                                                 Child,BT_PSave=SimpleButton(glstr(MSG_Save)),
  585.                                                                 Child,BT_PCancel=SimpleButton(glstr(MSG_Cancel)),
  586.                                                                 End,
  587.                                                             End,
  588.                                                         End,
  589.                                                     End;
  590.                                             }
  591.  
  592.                                             if(AP_SCDP)
  593.                                             {
  594.                                                 set(BT_ProgramR,MUIA_ShortHelp,glstr(MSG_HelpProgramR));
  595.                                                 set(BT_List,MUIA_ShortHelp,glstr(MSG_HelpList));
  596.                                                 set(BT_Use,MUIA_ShortHelp,glstr(MSG_HelpUse));
  597.                                                 set(BT_Save,MUIA_ShortHelp,glstr(MSG_HelpSave));
  598.                                                 set(BT_Cancel,MUIA_ShortHelp,glstr(MSG_HelpCancel));
  599.                                                 set(BT_PUse,MUIA_ShortHelp,glstr(MSG_HelpUse));
  600.                                                 set(BT_PSave,MUIA_ShortHelp,glstr(MSG_HelpSave));
  601.                                                 set(BT_PCancel,MUIA_ShortHelp,glstr(MSG_HelpCancel));
  602.                                                 set(BT_PNew,MUIA_ShortHelp,glstr(MSG_HelpNew));
  603.                                                 set(BT_PDelete,MUIA_ShortHelp,glstr(MSG_HelpDelete));
  604.                                                 set(BT_PTop,MUIA_ShortHelp,glstr(MSG_HelpTop));
  605.                                                 set(BT_PUp,MUIA_ShortHelp,glstr(MSG_HelpUp));
  606.                                                 set(BT_PDown,MUIA_ShortHelp,glstr(MSG_HelpDown));
  607.                                                 set(BT_PBottom,MUIA_ShortHelp,glstr(MSG_HelpBottom));
  608.  
  609.                                                 DoMethod(WI_SCDP,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,AP_SCDP,2,MUIM_Application_ReturnID,MUIV_Application_ReturnID_Quit);
  610.                                                 DoMethod(WI_List,MUIM_Window_SetCycleChain,ST_Artist,ST_CDTitle,ST_Title,CH_AutoPlay,CH_AutoProgram,CH_AutoShuffle,CH_AutoRepeat,BT_Use,BT_Save,BT_Cancel,NULL);
  611.                                                 DoMethod(WI_Program,MUIM_Window_SetCycleChain,LV_PList,BT_PNew,BT_PDelete,BT_PTop,BT_PUp,BT_PDown,BT_PBottom,LV_Program,BT_PUse,BT_PSave,BT_PCancel,NULL);
  612.  
  613.                                                 DoMethod(BT_Shuffle,MUIM_Notify,MUIA_Selected,TRUE,BT_ProgramL,3,MUIM_Set,MUIA_Selected,FALSE);
  614.                                                 DoMethod(BT_ProgramL,MUIM_Notify,MUIA_Selected,TRUE,BT_Shuffle,3,MUIM_Set,MUIA_Selected,FALSE);
  615.                                                 DoMethod(CH_AutoShuffle,MUIM_Notify,MUIA_Selected,TRUE,CH_AutoProgram,3,MUIM_Set,MUIA_Selected,FALSE);
  616.                                                 DoMethod(CH_AutoProgram,MUIM_Notify,MUIA_Selected,TRUE,CH_AutoShuffle,3,MUIM_Set,MUIA_Selected,FALSE);
  617.  
  618.                                                 DoMethod(BT_List,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_List);
  619.                                                 DoMethod(BT_ProgramR,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_ProgramR);
  620.                                                 DoMethod(BT_Play,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Play);
  621.                                                 DoMethod(BT_Pause,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Pause);
  622.                                                 DoMethod(BT_Stop,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Stop);
  623.                                                 DoMethod(BT_Previous,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Previous);
  624.                                                 DoMethod(BT_Next,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Next);
  625.                                                 DoMethod(BT_Rewind,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Rewind);
  626.                                                 DoMethod(BT_FastForward,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_FastForward);
  627.                                                 DoMethod(BT_Eject,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Eject);
  628.                                                 DoMethod(BT_ProgramL,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_ProgramL);
  629.                                                 DoMethod(BT_Shuffle,MUIM_Notify,MUIA_Selected,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Shuffle);
  630.                                                 DoMethod(SL_Volume,MUIM_Notify,MUIA_Slider_Level,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Volume);
  631.  
  632.                                                 DoMethod(BT_Use,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Use);
  633.                                                 DoMethod(BT_Save,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_Save);
  634.                                                 DoMethod(BT_Cancel,MUIM_Notify,MUIA_Selected,FALSE,WI_List,3,MUIM_Set,MUIA_Window_Open,FALSE);
  635.                                                 DoMethod(WI_List,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,WI_List,3,MUIM_Set,MUIA_Window_Open,FALSE);
  636.  
  637.                                                 DoMethod(LV_TrackSelect,MUIM_Notify,MUIA_Listview_DoubleClick,TRUE,AP_SCDP,2,MUIM_Application_ReturnID,ID_TrackSelect);
  638.                                                 DoMethod(LV_TitleList,MUIM_Notify,MUIA_List_Active,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_ChangeActive);
  639.                                                 DoMethod(ST_Title,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_Confirm);
  640.                                                 DoMethod(ST_Title,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_Title);
  641.                                                 DoMethod(ST_Artist,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_CDTitle);
  642.                                                 DoMethod(ST_CDTitle,MUIM_Notify,MUIA_String_Acknowledge,MUIV_EveryTime,WI_List,3,MUIM_Set,MUIA_Window_ActiveObject,ST_Title);
  643.  
  644.                                                 DoMethod(BT_PUse,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_PUse);
  645.                                                 DoMethod(BT_PSave,MUIM_Notify,MUIA_Selected,FALSE,AP_SCDP,2,MUIM_Application_ReturnID,ID_PSave);
  646.                                                 DoMethod(BT_PCancel,MUIM_Notify,MUIA_Selected,FALSE,WI_Program,3,MUIM_Set,MUIA_Window_Open,FALSE);
  647.                                                 DoMethod(WI_Program,MUIM_Notify,MUIA_Window_CloseRequest,TRUE,WI_Program,3,MUIM_Set,MUIA_Window_Open,FALSE);
  648.                                                 DoMethod(LV_PList,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime,AP_SCDP,2,MUIM_Application_ReturnID,ID_PInsert);
  649.                                                 DoMethod(BT_PNew,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,1,MUIM_List_Clear);
  650.                                                 DoMethod(BT_PDelete,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,2,MUIM_List_Remove,MUIV_List_Remove_Active);
  651.                                                 DoMethod(BT_PTop,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Top);
  652.                                                 DoMethod(BT_PTop,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Top);
  653.                                                 DoMethod(BT_PUp,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Previous);
  654.                                                 DoMethod(BT_PUp,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Up);
  655.                                                 DoMethod(BT_PDown,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Next);
  656.                                                 DoMethod(BT_PDown,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Down);
  657.                                                 DoMethod(BT_PBottom,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_List_Move,MUIV_List_Move_Active,MUIV_List_Move_Bottom);
  658.                                                 DoMethod(BT_PBottom,MUIM_Notify,MUIA_Selected,FALSE,LV_Program,3,MUIM_Set,MUIA_List_Active,MUIV_List_Active_Bottom);
  659.                                                 DoMethod(LV_Program,MUIM_Notify,MUIA_Listview_DoubleClick,MUIV_EveryTime,LV_Program,2,MUIM_List_Remove,MUIV_List_Remove_Active);
  660.  
  661.                                                 set(BT_List,MUIA_Disabled,TRUE);
  662.                                                 set(BT_ProgramR,MUIA_Disabled,TRUE);
  663.                                                 set(WI_SCDP,MUIA_Window_Open,TRUE);
  664.  
  665.                                                 if(!volumecontrol)
  666.                                                     set(SL_Volume,MUIA_Disabled,TRUE);
  667.  
  668.                                                 /*set(WI_Program,MUIA_Window_Open,TRUE);*/
  669.  
  670.                                                 i=vamos=TRUE;
  671.                                                 signals=0;
  672.                                                 CDSetVolume(-1);
  673.  
  674.                                                 while(i)
  675.                                                 {
  676.                                                     if(signals&(1<<tmsgport->mp_SigBit))
  677.                                                     {
  678.                                                         GetMsg(tmsgport);
  679.                                                         if(actuate)
  680.                                                         {
  681.                                                             get(BT_Repeat,MUIA_Selected,&a);
  682.                                                             if(pstatus==NORMAL)
  683.                                                             {
  684.                                                                 if(a)
  685.                                                                 {
  686.                                                                     track=1;
  687.                                                                     while((TOCflags[track-1]&1) && track<=TOClength)
  688.                                                                         track++;
  689.                                                                     if(track>TOClength)
  690.                                                                     {
  691.                                                                         CDStop();
  692.                                                                         track=0;
  693.                                                                     }
  694.                                                                     else
  695.                                                                     {
  696.                                                                         CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  697.                                                                         CDGetPos(FALSE);
  698.                                                                     }
  699.                                                                 }
  700.                                                                 else
  701.                                                                 {
  702.                                                                     CDStop();
  703.                                                                     track=0;
  704.                                                                 }
  705.                                                             }
  706.                                                             else
  707.                                                             {
  708.                                                                 pactual++;
  709.                                                                 if(!programmed[pactual-1] && a)
  710.                                                                 {
  711.                                                                     pactual=1;
  712.                                                                     if(pstatus==SHUFFLE)
  713.                                                                         DoShuffle();
  714.                                                                 }
  715.                                                                 if(!programmed[pactual-1])
  716.                                                                 {
  717.                                                                     CDStop();
  718.                                                                     track=0;
  719.                                                                 }
  720.                                                                 else
  721.                                                                 {
  722.                                                                     track=programmed[pactual-1];
  723.                                                                     CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  724.                                                                 }
  725.                                                             }
  726.                                                             actuate=0;
  727.                                                         }
  728.  
  729.                                                         CDGetPos(TRUE);
  730.                                                     }
  731.  
  732.                                                     b=DoMethod(AP_SCDP,MUIM_Application_Input,&signals);
  733.                                                     if((b==ID_Next || b==ID_Previous) && status!=PLAYING)
  734.                                                         b=ID_Play;
  735.                                                     switch(b)
  736.                                                     {
  737.                                                         case MEN_QUIT:
  738.                                                         case MUIV_Application_ReturnID_Quit:
  739.                                                             i=FALSE;
  740.                                                             break;
  741.                                                         case MEN_ABOUT:
  742.                                                             MUI_Request(AP_SCDP,WI_SCDP,0,NULL,glstr(MSG_AboutGadget),glstr(MSG_AboutText));
  743.                                                             break;
  744.                                                         case MEN_ABOUTMUI:
  745.                                                             if(!WI_AboutMUI)
  746.                                                                 WI_AboutMUI=AboutmuiObject,
  747.                                                                     MUIA_Window_RefWindow,WI_SCDP,
  748.                                                                     MUIA_Aboutmui_Application,AP_SCDP,
  749.                                                                     End;
  750.                                                             if(WI_AboutMUI)
  751.                                                                 set(WI_AboutMUI,MUIA_Window_Open,TRUE);
  752.                                                             else
  753.                                                                 DisplayBeep(0);
  754.                                                             break;
  755.                                                         case MEN_MUI:
  756.                                                             DoMethod(AP_SCDP,MUIM_Application_OpenConfigWindow,0);
  757.                                                             break;
  758.                                                         case ID_Volume:
  759.                                                             get(SL_Volume,MUIA_Slider_Level,&a);
  760.                                                             CDSetVolume(a);
  761.                                                             break;
  762.                                                         case ID_Play:
  763.                                                             switch(pstatus)
  764.                                                             {
  765.                                                                 case NORMAL:
  766.                                                                     switch(status)
  767.                                                                     {
  768.                                                                         case STOPPED:
  769.                                                                             track=1;
  770.                                                                             while((TOCflags[track-1]&1) && track<=TOClength)
  771.                                                                                 track++;
  772.                                                                             if(track>TOClength)
  773.                                                                             {
  774.                                                                                 CDStop();
  775.                                                                                 track=0;
  776.                                                                             }
  777.                                                                             else
  778.                                                                             {
  779.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  780.                                                                                 CDGetPos(FALSE);
  781.                                                                             }
  782.                                                                             break;
  783.                                                                         case PAUSED:
  784.                                                                             CDResume();
  785.                                                                             break;
  786.                                                                     }
  787.                                                                     break;
  788.                                                                 case SHUFFLE:
  789.                                                                     switch(status)
  790.                                                                     {
  791.                                                                         case STOPPED:
  792.                                                                             DoShuffle();
  793.                                                                             if(programmed[0])
  794.                                                                             {
  795.                                                                                 a=programmed[0];
  796.                                                                                 pactual=1;
  797.                                                                                 CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  798.                                                                                 CDGetPos(FALSE);
  799.                                                                             }
  800.                                                                             break;
  801.                                                                         case PAUSED:
  802.                                                                             CDResume();
  803.                                                                             break;
  804.                                                                     }
  805.                                                                     break;
  806.                                                                 case PROGRAM:
  807.                                                                     switch(status)
  808.                                                                     {
  809.                                                                         case STOPPED:
  810.                                                                             DoProgram();
  811.                                                                             if(programmed[0])
  812.                                                                             {
  813.                                                                                 a=programmed[0];
  814.                                                                                 pactual=1;
  815.                                                                                 CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  816.                                                                                 CDGetPos(FALSE);
  817.                                                                             }
  818.                                                                             break;
  819.                                                                         case PAUSED:
  820.                                                                             CDResume();
  821.                                                                             break;
  822.                                                                     }
  823.                                                                     break;
  824.                                                             }
  825.                                                             break;
  826.                                                         case ID_Eject:
  827.                                                             if(trayout)
  828.                                                             {
  829.                                                                 CDLoad();
  830.                                                                 trayout=FALSE;
  831.                                                             }
  832.                                                             else
  833.                                                             {
  834.                                                                 CDEject();
  835.                                                                 trayout=TRUE;
  836.                                                             }
  837.                                                             break;
  838.                                                         case ID_Pause:
  839.                                                             if(status==PAUSED)
  840.                                                                 CDResume();
  841.                                                             else
  842.                                                                 CDPause();
  843.                                                             break;
  844.                                                         case ID_Stop:
  845.                                                             CDStop();
  846.                                                             break;
  847.                                                         case ID_Rewind:
  848.                                                             if(status==PLAYING && actualindex<14400000 && actualindex>750)
  849.                                                             {
  850.                                                                 CDGetPos(FALSE);
  851.                                                                 totalindex-=750;
  852.                                                                 CDPlay(totalindex,TOCaddr[TOClength]-totalindex);
  853.                                                                 CDGetPos(FALSE);
  854.                                                             }
  855.                                                             break;
  856.                                                         case ID_FastForward:
  857.                                                             if(status==PLAYING && totalindex<TOCaddr[track]-750 && actualindex>0)
  858.                                                             {
  859.                                                                 CDGetPos(FALSE);
  860.                                                                 totalindex+=750;
  861.                                                                 CDPlay(totalindex,TOCaddr[TOClength]-totalindex);
  862.                                                                 CDGetPos(FALSE);
  863.                                                             }
  864.                                                             break;
  865.                                                         case ID_Previous:
  866.                                                             if(status==PLAYING)
  867.                                                             {
  868.                                                                 CDGetPos(FALSE);
  869.                                                                 if(totalindex-TOCaddr[track-1]>(75*5))
  870.                                                                 {
  871.                                                                     CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  872.                                                                 }
  873.                                                                 else
  874.                                                                 {
  875.                                                                     switch(pstatus)
  876.                                                                     {
  877.                                                                         case NORMAL:
  878.                                                                             if(onevalid)
  879.                                                                             {
  880.                                                                                 track--;
  881.                                                                                 if(!track)
  882.                                                                                     track=TOClength;
  883.                                                                                 while(TOCflags[track-1])
  884.                                                                                 {
  885.                                                                                     track--;
  886.                                                                                     if(!track)
  887.                                                                                         track=TOClength;
  888.                                                                                 }
  889.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  890.                                                                             }
  891.                                                                             break;
  892.                                                                         default:
  893.                                                                             if(onevalid && pactual>1)
  894.                                                                             {
  895.                                                                                 pactual--;
  896.                                                                                 track=programmed[pactual-1];
  897.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[track]-TOCaddr[track-1]);
  898.                                                                             }
  899.                                                                             break;
  900.                                                                     }
  901.                                                                 }
  902.                                                                 CDGetPos(FALSE);
  903.                                                             }
  904.                                                             break;
  905.                                                         case ID_Next:
  906.                                                             if(status==PLAYING)
  907.                                                             {
  908.                                                                 CDGetPos(FALSE);
  909.                                                                 {
  910.                                                                     switch(pstatus)
  911.                                                                     {
  912.                                                                         case NORMAL:
  913.                                                                             if(onevalid)
  914.                                                                             {
  915.                                                                                 track++;
  916.                                                                                 if(track>TOClength)
  917.                                                                                     track=1;
  918.                                                                                 while(TOCflags[track-1])
  919.                                                                                 {
  920.                                                                                     track++;
  921.                                                                                     if(track>TOClength)
  922.                                                                                         track=1;
  923.                                                                                 }
  924.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  925.                                                                             }
  926.                                                                             break;
  927.                                                                         default:
  928.                                                                             if(onevalid && programmed[pactual])
  929.                                                                             {
  930.                                                                                 pactual++;
  931.                                                                                 track=programmed[pactual-1];
  932.                                                                                 CDPlay(TOCaddr[track-1],TOCaddr[track]-TOCaddr[track-1]);
  933.                                                                             }
  934.                                                                             break;
  935.                                                                     }
  936.                                                                 }
  937.                                                                 CDGetPos(FALSE);
  938.                                                             }
  939.                                                             break;
  940.                                                         case ID_TrackSelect:
  941.                                                             get(LV_TrackSelect,MUIA_List_Active,&a);
  942.                                                             if(a>=0 && a<TOClength && !TOCflags[a])
  943.                                                             {
  944.                                                                 pstatus=NORMAL;
  945.                                                                 set(BT_ProgramL,MUIA_Selected,FALSE);
  946.                                                                 set(BT_Shuffle,MUIA_Selected,FALSE);
  947.                                                                 track=a+1;
  948.                                                                 CDPlay(TOCaddr[track-1],TOCaddr[TOClength]-TOCaddr[track-1]);
  949.                                                                 CDGetPos(FALSE);
  950.                                                             }
  951.                                                             break;
  952.                                                         case ID_ProgramL:
  953.                                                             get(BT_ProgramL,MUIA_Selected,&a);
  954.                                                             if(a)
  955.                                                             {
  956.                                                                 pstatus=PROGRAM;
  957.                                                                 DoProgram();
  958.                                                                 if(status==PLAYING && programmed[0])
  959.                                                                 {
  960.                                                                     a=programmed[0];
  961.  
  962.                                                                     CDPlay(TOCaddr[a-1],TOCaddr[TOClength]-TOCaddr[a-1]);
  963.                                                                     pactual=1;
  964.                                                                 }
  965.                                                                 else if(status!=STOPPED)
  966.                                                                     CDStop();
  967.                                                             }
  968.                                                             else
  969.                                                                 if(pstatus==PROGRAM)
  970.                                                                     pstatus=NORMAL;
  971.                                                             break;
  972.                                                         case ID_Shuffle:
  973.                                                             get(BT_Shuffle,MUIA_Selected,&a);
  974.                                                             if(a)
  975.                                                             {
  976.                                                                 pstatus=SHUFFLE;
  977.                                                                 DoShuffle();
  978.                                                                 if(status==PLAYING && programmed[0])
  979.                                                                 {
  980.                                                                     a=programmed[0];
  981.  
  982.                                                                     CDPlay(TOCaddr[a-1],TOCaddr[a]-TOCaddr[a-1]);
  983.                                                                     pactual=1;
  984.                                                                 }
  985.                                                                 else if(status!=STOPPED)
  986.                                                                     CDStop();
  987.                                                             }
  988.                                                             else
  989.                                                                 if(pstatus==SHUFFLE)
  990.                                                                     pstatus=NORMAL;
  991.                                                             break;
  992.                                                         case ID_List:
  993.                                                             FillList();
  994.                                                             break;
  995.                                                         case ID_ChangeActive:
  996.                                                             DoMethod(LV_TitleList,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  997.                                                             if(strptr)
  998.                                                             {
  999.                                                                 strcpy(buff,strptr);
  1000.                                                                 set(ST_Title,MUIA_String_Contents,buff+4);
  1001.                                                             }
  1002.                                                             break;
  1003.                                                         case ID_Confirm:
  1004.                                                             get(ST_Title,MUIA_String_Contents,&strptr);
  1005.                                                             get(LV_TitleList,MUIA_List_Active,&a);
  1006.                                                             if(a>=0 && a<TOClength)
  1007.                                                             {
  1008.                                                                 sprintf(buff,"%02d: %s",a+1,strptr);
  1009.                                                                 set(LV_TitleList,MUIA_List_Quiet,TRUE);
  1010.                                                                 DoMethod(LV_TitleList,MUIM_List_Remove,a);
  1011.                                                                 DoMethod(LV_TitleList,MUIM_List_InsertSingle,buff,a);
  1012.                                                                 set(LV_TitleList,MUIA_List_Quiet,FALSE);
  1013.                                                             }
  1014.                                                             break;
  1015.                                                         case ID_Save:
  1016.                                                             {
  1017.                                                                 FILE *f;
  1018.                                                                 char *s1, *s2;
  1019.                                                                 int a,b,c,d;
  1020.                                                                 sprintf(buff,"PROGDIR:Disks/%s",TOCCDID);
  1021.                                                                 if(f=fopen(buff,"w"))
  1022.                                                                 {
  1023.                                                                     get(ST_Artist,MUIA_String_Contents,&s1);
  1024.                                                                     get(ST_CDTitle,MUIA_String_Contents,&s2);
  1025.                                                                     fprintf(f,"%s\n%s\n",s1,s2);
  1026.                                                                     for(a=0;a<TOClength;a++)
  1027.                                                                     {
  1028.                                                                         DoMethod(LV_TitleList,MUIM_List_GetEntry,a,&strptr);
  1029.                                                                         fprintf(f,"%s\n",((char *)strptr)+4);
  1030.                                                                     }
  1031.                                                                     get(CH_AutoPlay,MUIA_Selected,&a);
  1032.                                                                     get(CH_AutoProgram,MUIA_Selected,&b);
  1033.                                                                     get(CH_AutoShuffle,MUIA_Selected,&c);
  1034.                                                                     get(CH_AutoRepeat,MUIA_Selected,&d);
  1035.                                                                     fprintf(f,"*%c\n",'0'+(a)+(b<<1)+(c<<2)+(d<<3));
  1036.                                                                     fclose(f);
  1037.                                                                 }
  1038.                                                             }
  1039.                                                         case ID_Use:
  1040.                                                             get(ST_Artist,MUIA_String_Contents,&strptr);
  1041.                                                             strcpy(TOCCDartist,strptr);
  1042.                                                             get(ST_CDTitle,MUIA_String_Contents,&strptr);
  1043.                                                             strcpy(TOCCDtitle,strptr);
  1044.                                                             set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1045.                                                             DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1046.                                                             for(a=0;a<TOClength;a++)
  1047.                                                             {
  1048.                                                                 DoMethod(LV_TitleList,MUIM_List_GetEntry,a,&strptr);
  1049.                                                                 DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1050.                                                             }
  1051.                                                             set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1052.                                                             refresh=TRUE;
  1053.                                                             set(WI_List,MUIA_Window_Open,FALSE);
  1054.                                                             CDGetPos(FALSE);
  1055.                                                             break;
  1056.                                                         case ID_PInsert:
  1057.                                                             DoMethod(LV_PList,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  1058.                                                             if(strptr)
  1059.                                                             {
  1060.                                                                 DoMethod(LV_Program,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1061.                                                             }
  1062.                                                             break;
  1063.                                                         case ID_ProgramR:
  1064.                                                             set(LV_Program,MUIA_List_Quiet,TRUE);
  1065.                                                             DoMethod(LV_Program,MUIM_List_Clear);
  1066.                                                             a=0;
  1067.                                                             while(pprog[a])
  1068.                                                             {
  1069.                                                                 DoMethod(LV_TrackSelect,MUIM_List_GetEntry,pprog[a]-1,&strptr);
  1070.                                                                 DoMethod(LV_Program,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1071.                                                                 a++;
  1072.                                                             }
  1073.                                                             set(LV_Program,MUIA_List_Quiet,FALSE);
  1074.                                                             set(WI_Program,MUIA_Window_ActiveObject,LV_PList);
  1075.                                                             set(WI_Program,MUIA_Window_Open,TRUE);
  1076.                                                             break;
  1077.                                                         case ID_PUse:
  1078.                                                             a=0;
  1079.                                                             do
  1080.                                                             {
  1081.                                                                 DoMethod(LV_Program,MUIM_List_GetEntry,a,&strptr);
  1082.                                                                 if(strptr)
  1083.                                                                 {
  1084.                                                                     pprog[a]=(strptr[0]-'0')*10+strptr[1]-'0';
  1085.                                                                     a++;
  1086.                                                                 }
  1087.                                                             }while(strptr);
  1088.                                                             pprog[a]=0;
  1089.                                                             set(WI_Program,MUIA_Window_Open,FALSE);
  1090.                                                             break;
  1091.                                                         case ID_PSave:
  1092.                                                             a=0;
  1093.                                                             do
  1094.                                                             {
  1095.                                                                 DoMethod(LV_Program,MUIM_List_GetEntry,a,&strptr);
  1096.                                                                 if(strptr)
  1097.                                                                 {
  1098.                                                                     pprog[a]=(strptr[0]-'0')*10+strptr[1]-'0';
  1099.                                                                     a++;
  1100.                                                                 }
  1101.                                                             }while(strptr);
  1102.                                                             pprog[a]=0;
  1103.                                                             sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1104.                                                             buff[14]='P';
  1105.                                                             buff[15]='R';
  1106.                                                             if(f=fopen(buff,"w"))
  1107.                                                             {
  1108.                                                                 a=0;
  1109.  
  1110.                                                                 while(pprog[a])
  1111.                                                                     putc(pprog[a++],f);
  1112.  
  1113.                                                                 fclose(f);
  1114.                                                             }
  1115.                                                             set(WI_Program,MUIA_Window_Open,FALSE);
  1116.                                                             break;
  1117.                                                         default:
  1118.                                                             break;
  1119.                                                     }
  1120.                                                     if(vamos)
  1121.                                                     {
  1122.                                                         CDGetPos(TRUE);
  1123.                                                         vamos=FALSE;
  1124.                                                     }
  1125.  
  1126.                                                     if(i && signals) signals=Wait(signals|(1<<tmsgport->mp_SigBit));
  1127.                                                 }
  1128.  
  1129.                                                 Wait(1<<tmsgport->mp_SigBit);
  1130.                                                 GetMsg(tmsgport);
  1131.                                             }
  1132.                                             else
  1133.                                             {
  1134.                                                 if(CL_ProgramList)
  1135.                                                     MUI_DeleteCustomClass(CL_ProgramList);
  1136.                                                 errorstr=glstr(MSG_FailApplication);
  1137.                                             }
  1138.  
  1139.                                             FreeMem(TOCbuf,MAX_TOC_LEN);
  1140.                                         }
  1141.                                         else
  1142.                                             errorstr=glstr(MSG_FailMemory);
  1143.  
  1144.                                         FreeMem(scsidata,MAX_DATA_LEN);
  1145.                                     }
  1146.                                     else
  1147.                                         errorstr=glstr(MSG_FailMemory);
  1148.  
  1149.                                     CloseDevice((struct IORequest *)tioreq);
  1150.                                 }
  1151.                                 else
  1152.                                     errorstr=glstr(MSG_FailNoTimer);
  1153.  
  1154.                                 DeleteIORequest(tioreq);
  1155.                             }
  1156.                             else
  1157.                                 errorstr=glstr(MSG_FailNoIO);
  1158.  
  1159.                             DeleteMsgPort(tmsgport);
  1160.                         }
  1161.                         else
  1162.                             errorstr=glstr(MSG_FailNoMP);
  1163.  
  1164.                         FreeMem(scsisense,SENSE_LEN);
  1165.                     }
  1166.                     else
  1167.                         errorstr=glstr(MSG_FailMemory);
  1168.  
  1169.                     FreeMem(scsicmd,sizeof(SCSICMD));
  1170.                 }
  1171.                 else
  1172.                     errorstr=glstr(MSG_FailMemory);
  1173.  
  1174.                 CloseDevice((struct IORequest *)ioreq);
  1175.             }
  1176.             else
  1177.                 errorstr=glstr(MSG_FailNoDevice);
  1178.  
  1179.             DeleteIORequest(ioreq);
  1180.         }
  1181.         else
  1182.             errorstr=glstr(MSG_FailNoIO);
  1183.  
  1184.         DeleteMsgPort(msgport);
  1185.     }
  1186.     else
  1187.         errorstr=glstr(MSG_FailNoMP);
  1188.  
  1189.     if(mydo)
  1190.         FreeDiskObject(mydo);
  1191.  
  1192.     fail(AP_SCDP,errorstr);
  1193.  
  1194.     return 0;
  1195. }
  1196.  
  1197. int DoScsiCmd(UBYTE *data, int datasize, UBYTE *cmd, int cmdsize, UBYTE flags)
  1198. {
  1199.     ioreq->io_Length=sizeof(SCSICMD);
  1200.     ioreq->io_Data=scsicmd;
  1201.     ioreq->io_Command=HD_SCSICMD;
  1202.  
  1203.     scsicmd->scsi_Data=(APTR)data;
  1204.     scsicmd->scsi_Length=datasize;
  1205.     scsicmd->scsi_SenseActual=0;
  1206.     scsicmd->scsi_SenseData=scsisense;
  1207.     scsicmd->scsi_Command=cmd;
  1208.     scsicmd->scsi_CmdLength=cmdsize;
  1209.     scsicmd->scsi_Flags=flags;
  1210.  
  1211.     DoIO((struct IORequest *) ioreq);
  1212.  
  1213.     return ioreq->io_Error;
  1214. }
  1215.  
  1216. void CDEject(void)
  1217. {
  1218.     static SCSICMD6 command=
  1219.     {
  1220.         SCSI_CMD_SSU,
  1221.         0,
  1222.         PAD,
  1223.         PAD,
  1224.         0,
  1225.         PAD,
  1226.     };
  1227.  
  1228.     int err;
  1229.  
  1230.     command.b4=2;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1231.  
  1232.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1233.         return;
  1234. }
  1235.  
  1236. void CDLoad(void)
  1237. {
  1238.     static SCSICMD6 command=
  1239.     {
  1240.         SCSI_CMD_SSU,
  1241.         0,
  1242.         PAD,
  1243.         PAD,
  1244.         0,
  1245.         PAD,
  1246.     };
  1247.  
  1248.     int err;
  1249.  
  1250.     command.b4=3;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1251.  
  1252.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1253.         return;
  1254. }
  1255.  
  1256. void CDStop(void)
  1257. {
  1258.     static SCSICMD6 command=
  1259.     {
  1260.         SCSI_CMD_SSU,
  1261.         0,
  1262.         PAD,
  1263.         PAD,
  1264.         0,
  1265.         PAD,
  1266.     };
  1267.  
  1268.     int err;
  1269.  
  1270.     command.b4=0;   /* I think this number is important: (0=STOP, 1=?, 2=EJECT, 3=LOAD, 4=STOP?)*/
  1271.  
  1272.     if(status==PLAYING || status==PAUSED)
  1273.         status=STOPPED;
  1274.  
  1275.     userstop=TRUE;
  1276.  
  1277.     if(err=DoScsiCmd(0,0,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1278.         return;
  1279. }
  1280.  
  1281. void CDGetPos(BOOL settimer)
  1282. {
  1283.     APTR *strptr;
  1284.     char buff[256];
  1285.     BOOL redraw=FALSE;
  1286.  
  1287.     static SCSICMD10 command=
  1288.     {
  1289.         SCSI_CMD_READSUBCHANNEL,
  1290.         0,
  1291.         0x40,
  1292.         0,
  1293.         PAD,
  1294.         PAD,
  1295.         0,
  1296.         0,0,
  1297.         PAD
  1298.     };
  1299.  
  1300.     int err;
  1301.     ULONG microsleft;
  1302.  
  1303.     command.b2=0x40;
  1304.     command.b3=1;
  1305.     command.b6=0;
  1306.     command.b7=255;
  1307.     command.b8=255;
  1308.  
  1309.     if(err=DoScsiCmd((UBYTE *)scsidata, MAX_DATA_LEN, (UBYTE *) &command, sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1310.     {
  1311.         track=0;
  1312.         status=NODISK;
  1313.         actualindex=totalindex=0;
  1314.         pstatus=NORMAL;
  1315.         if(validTOC)
  1316.         {
  1317.             set(WI_List,MUIA_Window_Open,FALSE);
  1318.             set(WI_Program,MUIA_Window_Open,FALSE);
  1319.             set(BT_List,MUIA_Disabled,TRUE);
  1320.             set(BT_ProgramR,MUIA_Disabled,TRUE);
  1321.             set(BT_ProgramL,MUIA_Selected,FALSE);
  1322.             set(BT_Shuffle,MUIA_Selected,FALSE);
  1323.             set(BT_Repeat,MUIA_Selected,FALSE);
  1324.             set(TX_Track,MUIA_Text_Contents,"--");
  1325.             set(TX_TitleTime,MUIA_Text_Contents,"--:--/--:--");
  1326.             set(TX_CDTime,MUIA_Text_Contents,"--:--/--:--");
  1327.             set(TX_Artist,MUIA_Text_Contents,glstr(MSG_NoDisc));
  1328.             set(TX_Title,MUIA_Text_Contents,"");
  1329.             DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1330.             DoMethod(LV_PList,MUIM_List_Clear);
  1331.             DoMethod(LV_Program,MUIM_List_Clear);
  1332.             pprog[0]=0;
  1333.             validTOC=0;
  1334.             microsleft=1000000;
  1335.         }
  1336.     }
  1337.     else
  1338.     {
  1339.         if(!validTOC)
  1340.         {
  1341.             CDReadContents();
  1342.         }
  1343.  
  1344.         /* Now one looks at scsidata[1]. It may be:
  1345.             0x11:   Playing.
  1346.             0x12:   Pause.
  1347.             other:  Stopped.
  1348.  
  1349.            scsidata[6] has the number of the track being played.
  1350.  
  1351.            scsidata[12..15] contains the address which is being played (75ths of second from track start).
  1352.            scsidata[8..11] contains the address from the begin of the CD.
  1353.         */
  1354.         switch(scsidata[1])
  1355.         {
  1356.             case 0x11:
  1357.                 if(status!=PLAYING)
  1358.                 {
  1359.                     status=PLAYING;
  1360.                     redraw=TRUE;
  1361.                 }
  1362.                 if(track!=scsidata[6])
  1363.                 {
  1364.                     track=scsidata[6];
  1365.                     redraw=TRUE;
  1366.                 }
  1367.                 trayout=FALSE;
  1368.                 actualindex=(scsidata[12] << 24) | (scsidata[13] << 16) | (scsidata[14] << 8) | (scsidata[15]);
  1369.                 totalindex=(scsidata[8] << 24) | (scsidata[9] << 16) | (scsidata[10] << 8) | (scsidata[11]);
  1370.                 microsleft=(75-(actualindex%75))*13333+25;
  1371.                 if(TOCaddr[track]-totalindex<80)
  1372.                 {
  1373.                     microsleft=(TOCaddr[track]-totalindex)*13333;
  1374.                     if(TOCaddr[TOClength]-totalindex<80 && !skip)
  1375.                         actuate=1;
  1376.                 }
  1377.                 if(pstatus!=NORMAL && track>programmed[pactual-1])
  1378.                 {
  1379.                     if(!skip)
  1380.                         actuate=2;
  1381.                     microsleft=1;
  1382.                 }
  1383.                 break;
  1384.             case 0x12:
  1385.                 status=PAUSED;
  1386.                 redraw=TRUE;
  1387.                 track=scsidata[6];
  1388.                 trayout=FALSE;
  1389.                 actualindex=(scsidata[12] << 24) | (scsidata[13] << 16) | (scsidata[14] << 8) | (scsidata[15]);
  1390.                 totalindex=(scsidata[8] << 24) | (scsidata[9] << 16) | (scsidata[10] << 8) | (scsidata[11]);
  1391.                 microsleft=1000000;
  1392.                 break;
  1393.             default:
  1394.                 status=STOPPED;
  1395.                 redraw=TRUE;
  1396.                 trayout=FALSE;
  1397.                 actualindex=totalindex=0;
  1398.                 track=0;
  1399.                 microsleft=1000000;
  1400.                 if(!userstop && !skip)
  1401.                     actuate=3;
  1402.                 break;
  1403.         }
  1404.  
  1405.         if(refresh)
  1406.         {
  1407.             redraw=TRUE;
  1408.             refresh=FALSE;
  1409.         }
  1410.  
  1411.         if(totalindex>=TOCaddr[TOClength])
  1412.         {
  1413.             if(!skip)
  1414.                 actuate=1;
  1415.             track=actualindex=totalindex=0;
  1416.         }
  1417.  
  1418.         if(track>0 && track<=TOClength)
  1419.         {
  1420.             if(pstatus==NORMAL || track==programmed[pactual-1])
  1421.                 set(LV_TrackSelect,MUIA_List_Active,track-1);
  1422.             sprintf(buff,"%02d",track);
  1423.             set(TX_Track,MUIA_Text_Contents,buff);
  1424.             sprintf(buff,"%02.2d:%02.2d/%02.2d:%02.2d",min(actualindex/(60*75),99),(actualindex/75)%60,(TOCaddr[track]-TOCaddr[track-1])/(60*75),((TOCaddr[track]-TOCaddr[track-1])/75)%60 );
  1425.             set(TX_TitleTime,MUIA_Text_Contents,buff);
  1426.             sprintf(buff,"%02.2d:%02.2d/%02.2d:%02.2d",totalindex/(60*75),(totalindex/75)%60,(TOCaddr[TOClength])/(60*75),((TOCaddr[TOClength])/75)%60 );
  1427.             set(TX_CDTime,MUIA_Text_Contents,buff);
  1428.             if(redraw)
  1429.             {
  1430.                 set(TX_Artist,MUIA_Text_Contents,TOCCDartist);
  1431.                 DoMethod(LV_TrackSelect,MUIM_List_GetEntry,MUIV_List_GetEntry_Active,&strptr);
  1432.                 if(pstatus==NORMAL || track==programmed[pactual-1])
  1433.                     set(TX_Title,MUIA_Text_Contents,((char *)strptr)+4);
  1434.             }
  1435.         }
  1436.         else
  1437.         {
  1438.             if(redraw)
  1439.             {
  1440.                 set(LV_TrackSelect,MUIA_List_Active,MUIV_List_Active_Off);
  1441.                 sprintf(buff,"--:--/%02.2d:%02.2d",(TOCaddr[TOClength])/(60*75),((TOCaddr[TOClength])/75)%60 );
  1442.                 set(TX_CDTime,MUIA_Text_Contents,buff);
  1443.                 set(TX_Track,MUIA_Text_Contents,"--");
  1444.                 set(TX_TitleTime,MUIA_Text_Contents,"--:--/--:--");
  1445.                 set(TX_Artist,MUIA_Text_Contents,TOCCDartist);
  1446.                 set(TX_Title,MUIA_Text_Contents,TOCCDtitle);
  1447.             }
  1448.         }
  1449.     }
  1450.     if(settimer)
  1451.     {
  1452.         if(skip)
  1453.             skip--;
  1454.         tioreq->tr_node.io_Command=TR_ADDREQUEST;
  1455.         tioreq->tr_time.tv_secs=microsleft/1000000;
  1456.         tioreq->tr_time.tv_micro=microsleft%1000000;
  1457.         SendIO((struct IORequest *)tioreq);
  1458.     }
  1459. }
  1460.  
  1461.  
  1462. /* THIS FUNCTION IS **NOT** SAFE!!!
  1463. ** I know it somehow works on my system, but I don't know how.
  1464. ** Anyway I leave it here, because I have nothing better. Perhaps I'll
  1465. ** find something better some day.        I DON'T KNOW HOW IT WORKS!!!
  1466. ** It takes a volume between 1 and 31.
  1467. */
  1468. void CDSetVolume(int volume)
  1469. {
  1470.     static SCSICMD6 modecommand;
  1471.     static struct volmodedata
  1472.     {
  1473.         UBYTE head[4];
  1474.         UBYTE page;     /* page code 0x0e */
  1475.         UBYTE plength;  /* page length */
  1476.         UBYTE b2;       /* bit2: Immed, bit 1: SOTC */
  1477.         UBYTE b3;       /* reserved */
  1478.         UBYTE b4;       /* reserved */
  1479.         UBYTE b5;       /* bit 7: APRVal, bit 3-0: format of LBAs / Sec. */
  1480.         UWORD bps;      /* logical blocks per second audio playback */
  1481.         UBYTE out0;     /* lower 4 bits: output port 0 channel selection */
  1482.         UBYTE vol0;     /* output port 0 volume */
  1483.         UBYTE out1;     /* lower 4 bits: output port 1 channel selection */
  1484.         UBYTE vol1;     /* output port 1 volume */
  1485.         UBYTE out2;     /* lower 4 bits: output port 2 channel selection */
  1486.         UBYTE vol2;     /* output port 2 volume */
  1487.         UBYTE out3;     /* lower 4 bits: output port 3 channel selection */
  1488.         UBYTE vol3;     /* output port 3 volume */
  1489.     } modedata;
  1490.     int i,err,j;
  1491.  
  1492.     if(!volumecontrol)
  1493.         return;
  1494.  
  1495.     for(i=0;i<4;i++)
  1496.         modedata.head[i]=0;
  1497.  
  1498.     modecommand.opcode=SCSI_CMD_MSE;
  1499.     modecommand.b1=0;            /* 0 */
  1500.     modecommand.b2=0x0e;         /* 0x0e */
  1501.     modecommand.b3=0;            /* 0 */
  1502.     modecommand.b4=64; /* MAX_DATA_LEN; */
  1503.     modecommand.control=0;
  1504.  
  1505.     if(err=DoScsiCmd((UBYTE *) scsidata, MAX_DATA_LEN, (UBYTE *) &modecommand, sizeof(modecommand), SCSIF_READ|SCSIF_AUTOSENSE))
  1506.         return;
  1507.  
  1508. /*    for(i=0;i<64;i++)
  1509.         printf("%02x",(int)scsidata[i]);
  1510.         printf("\n"); */
  1511.  
  1512.     for (j = (scsidata[0]+1), i = scsidata[3] + 4; i < j; i += scsidata[i+1] + 2)
  1513.         memcpy (&modedata.page, &scsidata[i], 16);
  1514.  
  1515.     modedata.page = 0x0e;
  1516.     modedata.plength = 0x0e;
  1517. /*    modedata.b2=4; */
  1518. /*    modedata.b5=0; */
  1519. /*    modedata.bps=NUM_OF_CDDAFRAMES; (0 en PlayCD)*/
  1520. /*    modedata.out0=1; */
  1521. /*    modedata.out1=2; */
  1522. /*    modedata.out2=0; */
  1523. /*    modedata.out3=0; */
  1524.  
  1525.     if(volume==-1)
  1526.     {
  1527.         volume=(modedata.vol0+modedata.vol1-2)/16;
  1528.         volume=max(1,min(31,volume));
  1529.         set(SL_Volume,MUIA_Slider_Level,volume);
  1530.     }
  1531.  
  1532.     modedata.vol0 = volume*8+1;
  1533.     modedata.vol1 = volume*8+1;
  1534.     modedata.vol2 = volume*8+1;
  1535.     modedata.vol3 = volume*8+1;
  1536.  
  1537.     modecommand.opcode      = SCSI_CMD_MSL;
  1538.     modecommand.b1          = 0x10;                /* 0 antes 0x10 */
  1539.     modecommand.b2          = 0;                   /* 0 */
  1540.     modecommand.b3          = 0;    /* 0x14 */
  1541.     modecommand.b4          = sizeof (modedata);   /* 0 */
  1542.     modecommand.control     = 0;
  1543.  
  1544.     if ((err = DoScsiCmd ((UBYTE *) &modedata, sizeof(modedata),
  1545.                           (UBYTE *) &modecommand, sizeof (modecommand),
  1546.                           (SCSIF_WRITE | SCSIF_AUTOSENSE))) != 0)
  1547.         return;
  1548.  
  1549. }
  1550.  
  1551. void CDPause(void)
  1552. {
  1553.     static SCSICMD10 command =
  1554.     {
  1555.         SCSI_CMD_PAUSERESUME,
  1556.         PAD,
  1557.         0,
  1558.         0,
  1559.         0,
  1560.         0,
  1561.         0,
  1562.         0,
  1563.         0,
  1564.         PAD,
  1565.     };
  1566.  
  1567.     command.b8 = 0x00; /* 0x01 for resuming */
  1568.  
  1569.     DoScsiCmd (NULL, NULL,
  1570.                (UBYTE *) & command, sizeof (command),
  1571.                (SCSIF_READ | SCSIF_AUTOSENSE));
  1572.     if(status==PLAYING)
  1573.         status=PAUSED;
  1574. }
  1575.  
  1576. void CDResume(void)
  1577. {
  1578.     static SCSICMD10 command =
  1579.     {
  1580.         SCSI_CMD_PAUSERESUME,
  1581.         PAD,
  1582.         0,
  1583.         0,
  1584.         0,
  1585.         0,
  1586.         0,
  1587.         0,
  1588.         0,
  1589.         PAD,
  1590.     };
  1591.  
  1592.     command.b8 = 0x01; /* 0x00 for pausing */
  1593.  
  1594.     DoScsiCmd (NULL, NULL,
  1595.                (UBYTE *) & command, sizeof (command),
  1596.                (SCSIF_READ | SCSIF_AUTOSENSE));
  1597. }
  1598.  
  1599. void CDPlay(int start, int length)
  1600. {
  1601.     static SCSICMD12 command =
  1602.     {
  1603.         SCSI_CMD_PLAYAUDIO12,
  1604.         PAD,
  1605.         0, 0, 0, 0,
  1606.         0, 0, 0, 0,
  1607.         PAD,
  1608.         PAD,
  1609.     };
  1610.     command.b2=(start&0xff000000)>>24;
  1611.     command.b3=(start&0x00ff0000)>>16;
  1612.     command.b4=(start&0x0000ff00)>>8;
  1613.     command.b5=(start&0x000000ff);
  1614.  
  1615.     command.b6=(length&0xff000000)>>24;
  1616.     command.b7=(length&0x00ff0000)>>16;
  1617.     command.b8=(length&0x0000ff00)>>8;
  1618.     command.b9=(length&0x000000ff);
  1619.  
  1620.     skip=5;
  1621.  
  1622.     userstop=FALSE;
  1623.     refresh=TRUE;
  1624.  
  1625.     DoScsiCmd((UBYTE *)scsidata,MAX_DATA_LEN,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE);
  1626. }
  1627.  
  1628. void CDReadContents(void)
  1629. {
  1630.     char buff[1024],buff2[256];
  1631.     FILE *f;
  1632.     static SCSICMD10 command=
  1633.     {
  1634.         SCSI_CMD_READTOC,
  1635.         0,
  1636.         PAD,PAD,PAD,PAD,
  1637.         0,
  1638.         0x03,0x24,
  1639.         PAD
  1640.     };
  1641.     int err,TOCsize;
  1642.     UBYTE * TOCptr;
  1643.  
  1644.     validTOC=0;
  1645.  
  1646.     if(err=DoScsiCmd((UBYTE *)TOCbuf,MAX_TOC_LEN,(UBYTE *)&command,sizeof(command),SCSIF_READ|SCSIF_AUTOSENSE))
  1647.         return;
  1648.  
  1649.     TOCsize=(TOCbuf[0]<<8)|TOCbuf[1];
  1650.  
  1651.     TOCaddr[2]=TOCaddr[1]=TOCaddr[0]=0;
  1652.     TOClength=0;
  1653.  
  1654.     if(TOCsize>=2);
  1655.         TOCsize-=2;
  1656.  
  1657.     onevalid=FALSE;
  1658.     for(TOCptr=&TOCbuf[4];TOCptr<(&TOCbuf[4]+TOCsize) && TOClength<100;TOCptr+=8)
  1659.     {
  1660.         TOCaddr[TOClength]=(TOCptr[4]<<24)|(TOCptr[5]<<16)|(TOCptr[6]<<8)|(TOCptr[7]);
  1661.         onevalid|=!((TOCflags[TOClength]=(TOCptr[1]&0x04)>>2)&1);
  1662.         TOClength++;
  1663.     }
  1664.     TOClength--;
  1665.  
  1666.     sprintf(TOCCDID,"ID%02d%06X%06X",TOClength,TOCaddr[2],TOCaddr[TOClength]);
  1667.  
  1668.     set(BT_ProgramL,MUIA_Selected,FALSE);
  1669.     set(BT_Shuffle,MUIA_Selected,FALSE);
  1670.     set(BT_Repeat,MUIA_Selected,FALSE);
  1671.     set(CH_AutoPlay,MUIA_Selected,FALSE);
  1672.     set(CH_AutoProgram,MUIA_Selected,FALSE);
  1673.     set(CH_AutoShuffle,MUIA_Selected,FALSE);
  1674.     set(CH_AutoRepeat,MUIA_Selected,FALSE);
  1675.  
  1676.     sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1677.     if(f=fopen(buff,"r"))
  1678.     {
  1679.         set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1680.         set(LV_PList,MUIA_List_Quiet,TRUE);
  1681.         DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1682.         DoMethod(LV_PList,MUIM_List_Clear);
  1683.         fgets(TOCCDartist,128,f);
  1684.         if(TOCCDartist[strlen(TOCCDartist)-1]=='\n')
  1685.             TOCCDartist[strlen(TOCCDartist)-1]='\0';
  1686.         fgets(TOCCDtitle,128,f);
  1687.         if(TOCCDtitle[strlen(TOCCDtitle)-1]=='\n')
  1688.             TOCCDtitle[strlen(TOCCDtitle)-1]='\0';
  1689.         for(err=0;err<TOClength;err++)
  1690.         {
  1691.             fgets(buff,128,f);
  1692.             if(buff[strlen(buff)-1]=='\n')
  1693.                 buff[strlen(buff)-1]='\0';
  1694.             sprintf(buff2,"%02d: %s",err+1,buff);
  1695.             DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1696.             DoMethod(LV_PList,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1697.         }
  1698.  
  1699.         fgets(buff,128,f);
  1700.         if(*buff=='*')
  1701.         {
  1702.             err=buff[1]&15;
  1703.             if(err&8)
  1704.             {
  1705.                 set(CH_AutoRepeat,MUIA_Selected,TRUE);
  1706.                 set(BT_Repeat,MUIA_Selected,TRUE);
  1707.             }
  1708.             if(err&4)
  1709.             {
  1710.                 set(CH_AutoShuffle,MUIA_Selected,TRUE);
  1711.                 set(BT_Shuffle,MUIA_Selected,TRUE);
  1712.             }
  1713.             if(err&2)
  1714.             {
  1715.                 set(CH_AutoProgram,MUIA_Selected,TRUE);
  1716.                 set(BT_ProgramL,MUIA_Selected,TRUE);
  1717.             }
  1718.             if(err&1)
  1719.             {
  1720.                 set(CH_AutoPlay,MUIA_Selected,TRUE);
  1721.                 DoMethod(AP_SCDP,MUIM_Application_ReturnID,ID_Play);
  1722.                 skip=5;
  1723.             }
  1724.         }
  1725.  
  1726.         fclose(f);
  1727.         set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1728.         set(LV_PList,MUIA_List_Quiet,FALSE);
  1729.     }
  1730.     else
  1731.     {
  1732.         set(LV_TrackSelect,MUIA_List_Quiet,TRUE);
  1733.         set(LV_PList,MUIA_List_Quiet,TRUE);
  1734.         DoMethod(LV_TrackSelect,MUIM_List_Clear);
  1735.         DoMethod(LV_PList,MUIM_List_Clear);
  1736.         strcpy(TOCCDartist,glstr(MSG_UnknownArtist));
  1737.         strcpy(TOCCDtitle,glstr(MSG_UnknownTitle));
  1738.         for(err=0;err<TOClength;err++)
  1739.         {
  1740.             if(TOCflags[err]&1)
  1741.                 sprintf(buff2,glstr(MSG_DataTrack),err+1);
  1742.             else
  1743.                 sprintf(buff2,glstr(MSG_TrackNo),err+1,err+1);
  1744.             DoMethod(LV_TrackSelect,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1745.             if(!TOCflags[err])
  1746.                 DoMethod(LV_PList,MUIM_List_InsertSingle,buff2,MUIV_List_Insert_Bottom);
  1747.         }
  1748.         set(LV_TrackSelect,MUIA_List_Quiet,FALSE);
  1749.         set(LV_PList,MUIA_List_Quiet,FALSE);
  1750.     }
  1751.     sprintf(buff,"PROGDIR:disks/%s",TOCCDID);
  1752.     buff[14]='P';
  1753.     buff[15]='R';
  1754.     if(f=fopen(buff,"r"))
  1755.     {
  1756.         int ppp,err;
  1757.  
  1758.         err=0;
  1759.  
  1760.         while((ppp=getc(f))!=EOF)
  1761.             pprog[err++]=(ppp>0 && ppp<=TOClength)?ppp:0;
  1762.  
  1763.         pprog[err]=0;
  1764.  
  1765.         fclose(f);
  1766.     }
  1767.     else
  1768.     {
  1769.         pprog[0]=0;
  1770.     }
  1771.     set(BT_List,MUIA_Disabled,FALSE);
  1772.     set(BT_ProgramR,MUIA_Disabled,FALSE);
  1773.     validTOC=1;
  1774. }
  1775.  
  1776. void DoShuffle(void)
  1777. {
  1778.     int i,j,mx=0,k;
  1779.  
  1780.     programmed[0]=0;
  1781.  
  1782.     if(!onevalid)
  1783.         return;
  1784.  
  1785.     srand(time(NULL));
  1786.  
  1787.     for(i=0;i<TOClength;i++)
  1788.         mx+=!TOCflags[i];
  1789.  
  1790.     for(i=0;i<mx;i++)
  1791.     {
  1792.         programmed[i]=rand()%TOClength;
  1793.         k=TRUE;
  1794.         while(k)
  1795.         {
  1796.             k=TOCflags[programmed[i]];
  1797.  
  1798.             for(j=0;j<i;j++)
  1799.                 k|=(programmed[j]==programmed[i]);
  1800.  
  1801.             if(k)
  1802.             {
  1803.                 programmed[i]++;
  1804.                 programmed[i]%=TOClength;
  1805.             }
  1806.         }
  1807.     }
  1808.     for(i=0;i<mx;i++)
  1809.         programmed[i]++;
  1810.     programmed[mx]=0;
  1811. }
  1812.  
  1813. void DoProgram(void)
  1814. {
  1815.     int i;
  1816.     i=0;
  1817.     while(programmed[i]=pprog[i])
  1818.         i++;
  1819. }
  1820.  
  1821. void FillList(void)
  1822. {
  1823.     int i;
  1824.     UBYTE *strptr;
  1825.  
  1826.     set(ST_Artist,MUIA_String_Contents,TOCCDartist);
  1827.     set(ST_CDTitle,MUIA_String_Contents,TOCCDtitle);
  1828.     set(LV_TitleList,MUIA_List_Quiet,TRUE);
  1829.     DoMethod(LV_TitleList,MUIM_List_Clear);
  1830.     for(i=0;i<TOClength;i++)
  1831.     {
  1832.         DoMethod(LV_TrackSelect,MUIM_List_GetEntry,i,&strptr);
  1833.         DoMethod(LV_TitleList,MUIM_List_InsertSingle,strptr,MUIV_List_Insert_Bottom);
  1834.     }
  1835.     set(LV_TitleList,MUIA_List_Active,0);
  1836.     set(LV_TitleList,MUIA_List_Quiet,FALSE);
  1837.     set(WI_List,MUIA_Window_ActiveObject,ST_Artist);
  1838.     set(WI_List,MUIA_Window_Open,TRUE);
  1839. }
  1840.  
  1841.